﻿#include "daocloudscos.h"

#include "src/config/ErrorCode.h"
#include "src/config/baseexception.h"
#include "src/config/loggerproxy.h"
#include "src/middle/manglobal.h"
#include <QDebug>
#ifdef _WIN32
#    include "cos_api.h"
#endif   // _WIN32

using namespace qcloud_cos;

DaoCloudsCos::DaoCloudsCos()
{
    m_config = new CosConfig("./config.json");
}
DaoCloudsCos::~DaoCloudsCos()
{
    delete m_config;
    m_config = nullptr;
}
QList<MyBucket> DaoCloudsCos::buckets()
{
    QList<MyBucket> res;
    GetServiceReq   req;
    GetServiceResp  resp;
    CosAPI          cos = qcloud_cos::CosAPI(*m_config);

    CosResult result = cos.GetService(req, &resp);

    if (result.IsSucc()) {


        std::vector<Bucket> bs = resp.GetBuckets();
        for (std::vector<Bucket>::const_iterator itr = bs.begin(); itr != bs.end(); ++itr) {
            const Bucket& v = *itr;

            MyBucket b;
            b.name       = QString(v.m_name.c_str());
            b.location   = QString(v.m_location.c_str());
            b.createDate = QString(v.m_create_date.c_str());
            res.append(b);
        }
    }
    else {

        throwError(EC_211000, result);
    }

    return res;
}

QList<MyBucket> DaoCloudsCos::login(const QString& secretId, const QString& secretKey)
{

    m_config->SetAccessKey(secretId.toStdString());
    m_config->SetSecretKey(secretKey.toStdString());

    return buckets();
}

bool DaoCloudsCos::isBucketExists(const QString& bucketName)
{
    MyBucket bucket = getBucketByName(bucketName);
    return bucket.isValid();
}

QString DaoCloudsCos::getBucketLocation(const QString& bucketName)
{
    CosAPI  cos = CosAPI(*m_config);
    QString location(cos.GetBucketLocation(bucketName.toStdString()).c_str());
    if (location != "") { return location; }
    MyBucket bucket = getBucketByName(bucketName);
    if (bucket.isValid()) { return bucket.location; }
    throw BaseException(EC_332000, QString::fromLocal8Bit("获取桶位置失败 %1").arg(bucketName));
}

void DaoCloudsCos::putBucket(const QString& bucketName, const QString& location)
{
    // 1. 指定配置文件路径，初始化 CosConfig
    qcloud_cos::CosConfig config("./config.json");
    qcloud_cos::CosAPI    cos(config);
    // 2. 构造创建存储桶的请求
    std::string bucket_name =
        "examplebucket-1250000000";   // 替换为用户的存储桶名，由 bucketname-appid 组成，appid
                                      // 必须填入，可以在 COS 控制台查看存储桶名称。
    qcloud_cos::PutBucketReq  req(bucket_name);
    qcloud_cos::PutBucketResp resp;
    qcloud_cos::CosResult     result = cos.PutBucket(req, &resp);
    // 4. 处理调用结果
    if (result.IsSucc()) {
        // 创建成功
    }
    else {
        // 创建存储桶失败，可以调用 CosResult 的成员函数输出错误信息，例如 requestID 等
        std::cout << "HttpStatus=" << result.GetHttpStatus() << std::endl;
        std::cout << "ErrorCode=" << result.GetErrorCode() << std::endl;
        std::cout << "ErrorMsg=" << result.GetErrorMsg() << std::endl;
        std::cout << "ResourceAddr=" << result.GetResourceAddr() << std::endl;
        std::cout << "XCosRequestId=" << result.GetXCosRequestId() << std::endl;
        std::cout << "XCosTraceId=" << result.GetXCosTraceId() << std::endl;
    }
}

void DaoCloudsCos::deleteBucket(const QString& bucketName) {}

QList<MyObject> DaoCloudsCos::getObjects(const QString& bucketName, const QString& dir)
{
    return QList<MyObject>();
}

void DaoCloudsCos::putObject(const QString& bucketName, const QString& key,
                             const QString& localPath, const TransProgressCallback& callback)
{}

void DaoCloudsCos::getObject(const QString& bucketName, const QString& key,
                             const QString& localPath, const TransProgressCallback& callback)
{}



QList<MyObject> DaoCloudsCos::getDirList(qcloud_cos::GetBucketResp& rsp, const QString& dir)
{
    return QList<MyObject>();
}

QList<MyObject> DaoCloudsCos::getFileList(qcloud_cos::GetBucketResp& rsp, const QString& dir)
{
    return QList<MyObject>();
}

void DaoCloudsCos::throwError(const QString& code, qcloud_cos::CosResult& result)
{
    QString msg = QString::fromLocal8Bit("腾讯云错误码【%1】： %2")
                      .arg(result.GetErrorCode().c_str(), result.GetErrorMsg().c_str());
    throw BaseException(code, msg);
}

MyBucket DaoCloudsCos::getBucketByName(const QString& bucketName)
{
    QList<MyBucket> bs = buckets();
    for (const auto& b : qAsConst(bs)) {
        if (b.name == bucketName) { return b; }
    }

    return MyBucket();
}
